package wangwenjun.phase3.concurrentcollections.concurrenthashmap;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ChangLiang
 * @date 2020/6/26
 */
@Slf4j
public class AppV3Test {

    private static ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

    private String name = "changliang";

    @Test
    @DisplayName("test")
    public void test() throws InterruptedException {
        map.put(name, 0);
        ScoreAddThread thread1 = new ScoreAddThread();
        thread1.start();
        ScoreAddThread thread2 = new ScoreAddThread();
        thread2.start();
        thread1.join();
        thread2.join();
        log.info("result:{}", map);
    }


    class ScoreAddThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {

                while (true) {
                    /**
                     * concurrentHashMap对于同时get和同时put都是线程安全的
                     * 但是其不能保证你get 然后在put 这样的组合操作是线程安全的
                     *
                     * ConcurrentHashMap replace方法 CAS的方式
                     */
                    Integer score = map.get(name);
                    boolean replaceResult = map.replace(name, score, score + 1);
                    if (replaceResult) {
                        break;
                    }
                }
            }
        }
    }
}
